#include <iostream>
#include <tins/tins.h>
#include <string>  
#include <tins/pdu.h>
#include <tins/ip.h>
#include <vector>
#include "functions.h"

#define NUM_PDUS 51
#define IP_NUM 28
#define MAX_STARS 30

using namespace Tins;

 
int main() {
	
	// Ensures all of the counts are initially 0
	// May not make a difference in debugging mode
	// but could certainly in release
	for(int i=0; i<NUM_PDUS; i++)
		pduCount[i] = 0; 

	std::cout << std::endl << "Welcome. Input the device you want to monitor (eth0): ";
	std::string deviceName, inputString; 
	std::cin >> deviceName; 
		
	// This call exits with an error if the device
	// can not be found
	Sniffer devSniff(deviceName, 10000, true);	// Initializes devSniff with 10,000 bytes max size
							// and in promiscuous mode (true) 


	// Asks the user if they want to enter more options
	// Otherwise we stick with defaults (no filters)
	std::cout << "More Options (yes/no)?: "; 
	if(userY())
	{
		std::cout << std::endl << "Filter (yes/no)?: "; 		
		if(userY())
		{
			std::cout << std::endl << "Input filter using libpcap syntax: ";
            		std::cin.ignore(256, '\n');	// Necessary because otherwise it will advance
							// without the user getting a chance to input
            		std::getline(std::cin, inputString); 	// getline instead of cin because 
								// libpcap syntax includes spaces
            		devSniff.set_filter(inputString); 	// Set the libpcap filter for our sniffer
			std::cin.clear(); 
            		//std::cin.ignore(256, '\n');
			//std::cout << std::endl << "Press Enter: " << std::endl;
		}	 
	}


	bool continueW = false;	// Whether or not to continue asking to capture packets 	
	do{
		std::cout << std::endl << "How many packets do you want to capture (-1 for infinity)?: "; 
		std::cin >> inputString; 

        	bool infinite = false; 
		int limit = atoi(inputString.c_str());	// Unchecked conversion to int from string
							// this should be checked for security in a 
							// later revision

		// If user enters -1 we will capture packets in an infinite loop
        	if(limit == -1)
            		infinite = true; 

		for(int j=0; j<limit || infinite; j++)
		{
			PDU * tempPDU = devSniff.next_packet();
			// The PDU must be cloned so that it is not corrupted when
			// it is being dissected by pduDissector and updateStats
			// You should ALWAYS clone PDUs when giving them to functions
			// that might change them so we don't read the same PDU somewhere
			// else and find it is corrupt 
			pduDissector(tempPDU->clone(), j); 
			updateStats(tempPDU->clone()); 
		}
		
		std::cout << std::endl << "Would you like to see a summary of the capture (yes/no)?: "; 
		if(userY()){
			showStats(); 
		}

	
		std::cout << std::endl << "Capture more packets (yes/no)?: ";
		if(userY())
			continueW = true; 
		else
			continueW = false; 

	}while(continueW); 

	return 0; 
}


